﻿using NDK.Motion.Card;
using NDK.Motion.MachineResources;
using NDK.Motion.Properties;
using System;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NDK.Motion.Frm
{
    public enum LampStatus
    {
        /// <summary>
        /// 正常
        /// </summary>
        ON,
        /// <summary>
        /// 关闭
        /// </summary>
        OFF,
        /// <summary>
        /// 报警
        /// </summary>
        ALM
    }
    public partial class Dlg_AxisDebug : Form
    {
        private static log4net.ILog traceLogger = log4net.LogManager.GetLogger("Dlg_AxisDebug");

        private int _axisId;
        private string _axisName;
        private bool _isEnableUserLimit;//是否使用用户定义的软限位
        private bool _isRepeatRunning = false;//是否在往返运动中
        private DIR_ENUM _homeDir;
        private Axis _axis;
        private int _moveType;

        public Dlg_AxisDebug()
        {
            InitializeComponent();
        }
        private void Dlg_AxisConfig_Load(object sender, EventArgs e)
        {
            try
            {
                if (!this.Axis.GetServoOn())
                {
                    this.Axis.ServoOn();
                    if (this.Axis.GetServoOn() == true)
                    {
                        btn_ServoOn.BtnText = "Servo OFF";
                    }
                }
                if (this.Axis != null)
                {
                    tb_MaxVel.Text = this.Axis.HomeVel.ToString();
                    tb_DecAndAccTime.Text = this.Axis.HomeAcc.ToString();
                }
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
            this.timer1.Start();
        }

        public int AxisId
        {
            get { return this._axisId; }
            set
            {
                this._axisId = value;
            }
        }
        public string AxisName
        {
            get
            {
                return _axisName;
            }

            set
            {
                _axisName = value;
                this.Text = _axisName + "(ID:" + _axisId + ")";
            }
        }
        public bool IsEnableUserLimit
        {
            get
            {
                return _isEnableUserLimit;
            }

            set
            {
                _isEnableUserLimit = value;
            }
        }
        public DIR_ENUM HomeDir
        {
            get
            {
                return _homeDir;
            }

            set
            {
                _homeDir = value;
            }
        }

        public Axis Axis
        {
            get
            {
                return _axis;
            }

            set
            {
                _axis = value;
            }
        }
        private double MoveVel
        {
            get
            {
                double moveVel = 0.0;
                return double.TryParse(tb_MaxVel.Text.Trim(), out moveVel) ? moveVel : 0.0;
            }
        }
        private double MoveAccAndDec
        {
            get
            {
                double moveAcc = 0.0;
                return double.TryParse(tb_DecAndAccTime.Text.Trim(), out moveAcc) ? moveAcc : 0.0;
            }
        }
        private double CmdPosition
        {
            get
            {
                double cmdPos = 0.0;
                return double.TryParse(tb_CmdPos.Text.Trim(), out cmdPos) ? cmdPos : 0.0;
            }
        }

        #region UI
        private void ucBtnImg_MouseEffected(object sender, EventArgs e)
        {
            var btn = sender as HZH_Controls.Controls.UCBtnExt;
            btn.FillColor = Color.FromArgb(204, 204, 205);
        }

        private void ucBtnImg_MouseEffecting(object sender, EventArgs e)
        {
            var btn = sender as HZH_Controls.Controls.UCBtnExt;
            btn.FillColor = Color.FromArgb(174, 218, 151);
        }


        #endregion

        private void btn_EmgStop_BtnClick(object sender, EventArgs e)
        {
            try
            {
                this.Axis.StopMoveEmg();
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void btn_DecStop_BtnClick(object sender, EventArgs e)
        {
            try
            {
                this.Axis.StopMoveDec();
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void btn_ServoOn_BtnClick(object sender, EventArgs e)
        {
            try
            {
                if (this.Axis.GetServoOn())
                {
                    this.Axis.ServoOff();
                    btn_ServoOn.BtnText = "Servo ON";
                }
                else
                {
                    this.Axis.ServoOn();
                    btn_ServoOn.BtnText = "Servo OFF";
                }
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void btn_HomeMove_BtnClick(object sender, EventArgs e)
        {
            Task homeTask = Task.Run(() =>
            {
                try
                {
                    if (this.Axis.HomeMove())
                    {
                        var ret = this.Axis.WaitHomeMoveDone();
                        if (ret != 0)
                            MessageBox.Show($"回零失败 retCode:{ret}");
                    }
                }
                catch (Exception ex)
                {
                    traceLogger.Error(ex.StackTrace);
                }
            });
        }

        private void btn_Positive_BtnClick(object sender, EventArgs e)
        {
            try
            {
                if (_moveType == 0)//运动到绝对位置
                {
                    this.Axis.MoveAbs(CmdPosition, MoveVel, MoveAccAndDec, MoveAccAndDec);
                }
                if (_moveType == 1)//运动相对距离
                {
                    this.Axis.MoveRel(CmdPosition, MoveVel, MoveAccAndDec, MoveAccAndDec);
                }
                if (_moveType == 2)//Jog 运动
                {
                    this.Axis.MoveJog(DIR_ENUM.Positive, MoveVel);
                }
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void rn_CheckedChanged(object sender, EventArgs e)
        {
            if (rb_AbsMove.Checked == true)
            {
                _moveType = 0;
            }
            if (rb_RelMove.Checked == true)
            {
                _moveType = 1;
            }
            if (rb_VelMove.Checked == true)
            {
                _moveType = 2;
            }
        }

        private void btn_Negative_BtnClick(object sender, EventArgs e)
        {
            try
            {
                if (_moveType == 0)//运动到绝对位置
                {
                    this.Axis.MoveAbs(CmdPosition, MoveVel, MoveAccAndDec, MoveAccAndDec);
                }
                if (_moveType == 1)//运动相对距离
                {
                    this.Axis.MoveRel(-CmdPosition, MoveVel, MoveAccAndDec, MoveAccAndDec);
                }
                //if (_moveType == 2)//Jog 运动
                //{
                //    this.Axis.MoveJog(DIR_ENUM.Negative, MoveVel);
                //}
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void btn_RepeatStop_BtnClick(object sender, EventArgs e)
        {
            _isRepeatRunning = false;
            Axis.StopMoveDec();
        }
        private void btn_RepeatStart_BtnClick(object sender, EventArgs e)
        {
            double startPos = Convert.ToDouble(this.tb_RepeatPos1.Text);
            double stopPos = Convert.ToDouble(this.tb_RepeatPos2.Text);

            if (this.Axis.IsEnableSoftLimit)
            {
                if ((startPos > this.Axis.SPel) || (stopPos < this.Axis.SMel))
                {
                    MessageBox.Show("起点位置不能超过软极限位");
                }
                else if ((startPos > this.Axis.SPel) || (stopPos < this.Axis.SMel))
                {
                    MessageBox.Show("终点位置不能超过软极限位");
                }
            }

            if (startPos == stopPos)
            {
                MessageBox.Show("终点位置与起点位置不能相同");
            }
            else
            {
                int times = int.Parse(this.tb_RepeatTime.Text);
                if (times < 0)
                {
                    MessageBox.Show("往返次数不能小于0");
                }
                else if (!this._isRepeatRunning)
                {
                    this.Axis.IsStop = false;
                    this._isRepeatRunning = true;
                    btn_Positive.Enabled = false;
                    btn_Negative.Enabled = false;
                    btn_SetPos.Enabled = false;
                    btn_RepeatStart.Enabled = false;
                    tb_DecAndAccTime.Enabled = false;
                    tb_RepeatDelay.Enabled = false;
                    tb_RepeatPos1.Enabled = false;
                    tb_RepeatPos2.Enabled = false;
                    tb_RepeatTime.Enabled = false;
                    tb_MaxVel.Enabled = false;
                    Task repeatTask = Task.Run(() =>
                    {
                        try
                        {
                            for (int i = 0; i < times; i++)
                            {
                                this.Axis.MoveAbs(double.Parse(tb_RepeatPos1.Text), double.Parse(tb_MaxVel.Text), double.Parse(tb_DecAndAccTime.Text), double.Parse(tb_DecAndAccTime.Text));
                                if (_isRepeatRunning == false) break;
                                if (this.Axis.WaitMoveDone(double.Parse(tb_RepeatPos1.Text)) == 2) break;
                                if (_isRepeatRunning == false) break;
                                Task.Delay(int.Parse(tb_RepeatDelay.Text)).Wait();
                                if (_isRepeatRunning == false) break;
                                this.Axis.MoveAbs(double.Parse(tb_RepeatPos2.Text), double.Parse(tb_MaxVel.Text), double.Parse(tb_DecAndAccTime.Text), double.Parse(tb_DecAndAccTime.Text));
                                if (_isRepeatRunning == false) break;
                                if (this.Axis.WaitMoveDone(double.Parse(tb_RepeatPos2.Text)) == 2) break;
                                if (_isRepeatRunning == false) break;
                                Task.Delay(int.Parse(tb_RepeatDelay.Text)).Wait();
                                if (_isRepeatRunning == false) break;
                            }
                        }
                        catch (Exception ex)
                        {
                            traceLogger.Error(ex.StackTrace);
                        }
                        this._isRepeatRunning = false;
                        btn_Positive.Enabled = true;
                        btn_Negative.Enabled = true;
                        btn_SetPos.Enabled = true;
                        btn_RepeatStart.Enabled = true;
                        tb_DecAndAccTime.Enabled = true;
                        tb_RepeatDelay.Enabled = true;
                        tb_RepeatPos1.Enabled = true;
                        tb_RepeatPos2.Enabled = true;
                        tb_RepeatTime.Enabled = true;
                        tb_MaxVel.Enabled = true;
                    });
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (Axis?.Card.Initialized == true)
            {
                tb_FeedbankPos.Text = Axis?.GetPos().ToString("0.0000");

                //SVON
                if (Axis?.GetServoOn() == true) pb_ServoOn.BackgroundImage = Resources.LightOn; else pb_ServoOn.BackgroundImage = Resources.LightOff;
                //INP
                //if (Axis?.GeINP() == true) pb_INP.BackgroundImage = Resources.LightOn; else pb_INP.BackgroundImage = Resources.LightOff;
                //EMG
                if (Axis?.GetEMG() == true) pb_EMG.BackgroundImage = Resources.LightOn; else pb_EMG.BackgroundImage = Resources.LightOff;
                //ORG
                if (Axis?.GetORG() == true) pb__ORG.BackgroundImage = Resources.LightOn; else pb__ORG.BackgroundImage = Resources.LightOff;
                //MEL
                if (Axis?.GetMEL() == true) pb_MEL.BackgroundImage = Resources.LightOn; else pb_MEL.BackgroundImage = Resources.LightOff;
                //PEL
                if (Axis?.GetPEL() == true) pb_PEL.BackgroundImage = Resources.LightOn; else pb_PEL.BackgroundImage = Resources.LightOff;
                //ALM
                if (Axis?.GetAlarm() == true) pb_ALM.BackgroundImage = Resources.LightOn; else pb_ALM.BackgroundImage = Resources.LightOff;
                //ASTP
                //if (Axis?.GetASTP() == true) pb_ASTP.BackgroundImage = Resources.LightOn; else pb_ASTP.BackgroundImage = Resources.LightOff;
                //CSTP
                //if (Axis?.GetCSTP() == true) pb_CSTP.BackgroundImage = Resources.LightOn; else pb_CSTP.BackgroundImage = Resources.LightOff;
                //NSTP
                if (Axis?.GetNSTP() == true) pb_NSTP.BackgroundImage = Resources.LightOn; else pb_NSTP.BackgroundImage = Resources.LightOff;
                //HMV
                //if (Axis?.GetHMV() == true) pb_HMV.BackgroundImage = Resources.LightOn; else pb_HMV.BackgroundImage = Resources.LightOff;

                Application.DoEvents();
            }
        }


        private void Dlg_AxisDebug_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer1.Stop();
        }

        private void btn_SetPos_BtnClick(object sender, EventArgs e)
        {
            try
            {
                double pos = double.Parse(tb_SetPos.Text.Trim());
                this.Axis.SetPos(pos);
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }

        }

        private void btn_Jog_MouseDown(object sender, MouseEventArgs e)
        {

            try
            {
                DIR_ENUM dir = DIR_ENUM.Negative;
                if (sender is Button)
                {
                    if ((Button)sender == btn_Positive1)
                    {
                        dir = DIR_ENUM.Positive;
                    }
                }
                if (_moveType == 2)//Jog 运动
                {
                    this.Axis.MoveJog(dir, MoveVel);
                }
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
                MessageBox.Show("Jog 运动时失败！" + ex.Message);
            }
        }

        private void btn_Jog_MouseUp(object sender, MouseEventArgs e)
        {
            try
            {
                if (_moveType == 2)//Jog 停止
                {
                    this.Axis.StopMoveEmg();
                }
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void btn_ClearAlarm_BtnClick(object sender, EventArgs e)
        {
            try
            {
                this.Axis.ClearAlarm();
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }


    }
}
